package com.cloud.core.emchat;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.annotation.PostConstruct;

import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.cloud.core.httpclient.HttpClientProxy;
import com.cloud.core.redis.RedisClient;
import com.cloud.util.Notice;
import com.google.gson.JsonObject;

/**
 * 1Cloud1
 * @author Administrator
 * @since 2015-11-13
 * @version 1.0 
 */
@Component("ChatAdmin")
public class ChatAdmin {
	private static final Logger logger = LoggerFactory.getLogger(ChatAdmin.class);
	private final String BASE_REQUEST_URL = "https://#API_SERVER/#ORG_NAME/#APP_NAME/#METHOD";
	private String request_url;
	private String admin_token;
	@Value("${app_user_reg_open}")
	public String app_user_reg_open;
	@Value("${app_chat_msg_limit}")
	public String app_chat_msg_limit;
	
	@Autowired
	private HttpClientProxy HttpClientProxy;
	
	@Autowired
	private RedisClient RedisClient;
	
	public JsonObject createSingleUser(String userName, String passWord, String nikeName){
		boolean isOpen = Boolean.valueOf(app_user_reg_open).booleanValue();
		if(isOpen){
			return createSingleUserByOpen(userName, passWord, nikeName);
		} else {
			return createSingleUserByAuth(userName, passWord, nikeName);
		}
	}
	
	/**
	 * 修改密码
	 * @param userName 用户名
	 * @param newpassword 密码
     * curl -X PUT -H "Authorization: Bearer YWMtSozP9jHNEeSQegV9EKeAQAAAUlmBR2bTGr-GP2xNh8GhUCdKViBFgtox3M" -i  "https://a1.easemob.com/easemob-demo/chatdemoui/users/ywuxvxuir6/password" -d '{"newpassword" : "123456"}'
	 */
	public JsonObject changePwd(String userName, String newpassword){
		ObjectMapper mapper = new ObjectMapper();
		ObjectNode dataNode = mapper.createObjectNode();
		dataNode.put("newpassword",newpassword);
		String uri = getRequest_url().replace("#METHOD", "users") + "/" + userName + "/password";
		Header header = new BasicHeader("Authorization", "Bearer ".concat(getToken()));
		JsonObject obj = HttpClientProxy.getJsonObjectFromPut(uri, dataNode, header);
		logger.info(String.format("调用[%s]修改环信密码,返回值：[%s].", uri, obj.toString()));
		return obj;
	}
	
	/**
	 * 删除用户
	 * @param userName 用户名
     * curl -X DELETE -H "Authorization: Bearer YWMtSozP9jHNEeSQegV9EK5eAQAAAUlmBR2bTGr-GP2xNh8GhUCdKViBFgtox3M" -i  "https://a1.easemob.com/easemob-demo/chatdemoui/users/ywuxvxuir6"
	 */
	public JsonObject deleteUser(String userName){
		ObjectMapper mapper = new ObjectMapper();
		ObjectNode dataNode = mapper.createObjectNode();
		String uri = getRequest_url().replace("#METHOD", "users") + "/" + userName;
		Header header = new BasicHeader("Authorization", "Bearer ".concat(getToken()));
		JsonObject obj = HttpClientProxy.getJsonObjectFromDelete(uri, dataNode, header);
		logger.info(String.format("调用[%s]删除用户[%s],返回值：[%s].", uri, userName, obj.toString()));
		return obj;
	}
	
	/**
	 * 开放注册
	 * @param userName 用户名
	 * @param passWord 密码
	 * @param nikeName 昵称
     * curl -X POST -i "https://a1.easemob.com/easemob-demo/chatdemoui/users" -d '{"username":"jliu","password":"123456"}'
	 */
	private JsonObject createSingleUserByOpen(String userName, String passWord, String nikeName){
		ObjectMapper mapper = new ObjectMapper();
		ObjectNode dataNode = mapper.createObjectNode();
		if(userName != null && userName.trim().length() > 0)
			dataNode.put("username",userName);
		if(passWord != null && passWord.trim().length() > 0)
			dataNode.put("password", passWord);
		if(nikeName != null && nikeName.trim().length() > 0)
			dataNode.put("nickname", nikeName);
		String uri = getRequest_url().replace("#METHOD", "users");
		JsonObject obj = HttpClientProxy.getJsonObjectFromPost(uri, dataNode, null);
		logger.info(String.format("调用[%s]开放注册环信用户,返回值：[%s].", uri, obj.toString()));
		return obj;
	}
	
	/**
	 * 授权注册
	 * @param userName 用户名
	 * @param passWord 密码
	 * @param nikeName 昵称
     * curl -X POST -H "Authorization: Bearer YWMt39RfMMOqEeKYE_GW7tu81AAAAT71lGijyjG4VUIC2AwZGzUjVbPp_4qRD5k" -i  "https://a1.easemob.com/easemob-demo/chatdemoui/users" -d '{"username":"jliu","password":"123456"}'
	 */
	private JsonObject createSingleUserByAuth(String userName, String passWord, String nikeName){
		ObjectMapper mapper = new ObjectMapper();
		ObjectNode dataNode = mapper.createObjectNode();
		if(userName != null && userName.trim().length() > 0)
			dataNode.put("username",userName);
		if(passWord != null && passWord.trim().length() > 0)
			dataNode.put("password", passWord);
		String uri = getRequest_url().replace("#METHOD", "users");
		Header header = new BasicHeader("Authorization", "Bearer ".concat(getToken()));
		JsonObject obj = HttpClientProxy.getJsonObjectFromPost(uri, dataNode, header);
		logger.info(String.format("调用[%s]授权注册环信用户,返回值：[%s].", uri, obj.toString()));
		return obj;
	}
	
	/**
	 * 查询聊天记录
	 * @param ql
	 * curl -X GET -i -H "Authorization: Bearer YWMtxc6K0L1aEeKf9LWFzT9xEAAAAT7MNR_9OcNq-GwPsKwj_TruuxZfFSC2eIQ" "https://a1.easemob.com/easemob-demo/chatdemoui/chatmessages?ql=select+*+where+timestamp>1403164734226"
	 */
	public JsonObject getChatMessages(String lastTime){
		//同一个IP每秒最多可调用1次,
		try { Thread.sleep(1500); } catch (InterruptedException e1) { }
		String uri = getRequest_url().replace("#METHOD", "chatmessages");
		if(lastTime != null && lastTime.trim().length() > 0){
			String where = "select * where timestamp > ".concat(lastTime);
			try {
				uri.concat("?ql=").concat(URLEncoder.encode(where, "UTF-8"));
			} catch (UnsupportedEncodingException e) {
				uri.concat("?ql=").concat(where);
			}
		}
		Header header = new BasicHeader("Authorization", "Bearer ".concat(getToken()));
		JsonObject obj = HttpClientProxy.getJsonObjectFromGet(uri, header);
		logger.info(String.format("获取消息记录：[%s]成功,返回值：[%s].", uri, obj));
		return obj;
	}
	
	/**
	 * 发送消息
	 * @param from
	 * @param to
	 * @param notice
	 * curl -X POST -H "Authorization:Bearer YWMtxc6K0L1aEeKf9LWFzT9xEAAAAT7MNR_9OcNq-GwPsKwj_TruuxZfFSC2eIQ" -i "https://a1.easemob.com/easemob-demo/chatdemoui/messages" -d '{"target_type":"users","target":["testb","testc"],"msg":{"type":"cmd","action":"action1"},"from":"testa","ext":{"attr1":"v1","attr2":"v2"}}'
	 */
	public JsonObject sendMessage(String from, String to, Notice notice){
		/*ObjectNode dataNode = generalMsgNotice(from, to, notice);
		String uri = getRequest_url().replace("#METHOD", "messages");
		Header header = new BasicHeader("Authorization", "Bearer ".concat(getToken()));
		JsonObject obj = HttpClientProxy.getJsonObjectFromPost(uri, dataNode, header);
		logger.info(String.format("调用接口[%s]发送透传消息：[%s]成功,返回值：[%s].", uri, dataNode.toString(), obj));
		return obj;*/
		return null;
	}
	
	/**
	 * 分页导出聊天记录
	 * @param cursor
	 * curl -X GET -i -H "Authorization: Bearer YWMtxc6K0L1aEeKf9LWFzT9xEAAAAT7MNR_9OcNq-GwPsKwj_TruuxZfFSC2eIQ" "https://a1.easemob.com/easemob-demo/chatdemoui/chatmessages?limit=10&cursor=MTYxOTcyOTYyNDpnR2tBQVFNQWdHa0FCZ0ZHczFuSG93Q0FkUUFROW94S0lQZVBFZU9mTEQxQWVMdHEyQUNBZFFBUTlvd2pFUGVQRWVPaHFWa1l0ZjA2dEFB"
	 */
	public void exportChatMessages(String cursor){
		String uri = getRequest_url().replace("#METHOD", "chatmessages");
		uri.concat("?limit=").concat(getApp_chat_msg_limit());
		if(cursor != null && cursor.trim().length() > 0) {
			uri.concat("&cursor=").concat(cursor);
		}
		Header header = new BasicHeader("Authorization", "Bearer ".concat(getToken()));
		JsonObject obj = HttpClientProxy.getJsonObjectFromGet(uri, header);
		if(obj != null && obj.has("cursor")){
			//处理obj
			getChatMessages(obj.get("access_token").getAsString());
		} else {
			//处理obj
		}
	}
	
	@PostConstruct
	public void init() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					request_url = BASE_REQUEST_URL.replace("#API_SERVER", HttpClientProxy.getApi_server_host()).replace("#ORG_NAME", HttpClientProxy.getOrg_name()).replace("#APP_NAME", HttpClientProxy.getApp_name());
					admin_token = HttpClientProxy.getOrg_name().concat("_").concat(HttpClientProxy.getApp_name()).concat("_token");
					getToken();
				} catch (Exception e) {
					logger.error(String.format("初始化获取管理员Token出错：", e));
				}
			}
		}).start();
	}
	
	public String getToken(){
		String token = RedisClient.get(admin_token.toLowerCase());
		logger.info(String.format("从Redis中获取APP管理员Token：%s", token));
		if(token != null && token.trim().length() > 0)
			return token;
		return token();
	}
	
	/**
	 * 获取APP管理员Token
	 *   curl -X POST "https://a1.easemob.com/easemob-demo/chatdemoui/token" -d '{"grant_type":"client_credentials","client_id":"YXA6wDs-MARqEeSO0VcBzaqg11","client_secret":"YXA6JOMWlLap_YbI_ucz77j-4-mI0dd"}'
	 *   Response Body ：{"access_token":"YWMtnOO1MInTEeWzdOkGzWMb5gAAAVI0nsaKZfburrqm3gpymUuDCTLya-l5niY","expires_in":5184000,"application":"3f239f90-89c5-11e5-af2b-dbb5003dc2bb"}
	 */
	private String token() {
		String token = "";
		String uri = getRequest_url().replace("#METHOD", "token");
		logger.debug(String.format("开始获取APP管理员Token：%s", uri));
		ObjectMapper mapper = new ObjectMapper();
		ObjectNode dataNode = mapper.createObjectNode();
		dataNode.put("grant_type", "client_credentials");
		dataNode.put("client_id", HttpClientProxy.getApp_client_id());
		dataNode.put("client_secret", HttpClientProxy.getApp_client_secret());
		JsonObject obj = HttpClientProxy.getJsonObjectFromPost(uri, dataNode, null);
		if(obj != null && obj.has("access_token")){
			token = obj.get("access_token").getAsString();
			int valid = obj.get("expires_in").getAsInt();
			logger.info(String.format("获取APP管理员Token：[%s]成功,有效期为：[%s]秒.", token, valid));
			RedisClient.setString(admin_token.toLowerCase(), token, valid);
		}
		return token;
	}
	
	/**
	 * 构建ObjectNode
	 * @param from
	 * @param to
	 * @param type
	 * @return
	 * {
			"target_type":"users",     // users 给用户发消息,  chatgroups 给群发消息
			"target":["testb","testc"], // 注意这里需要用数组,数组长度建议不大于20, 即使只有  
		                                // 一个用户u1或者群组, 也要用数组形式 ['u1'], 给用户发  
		                                // 送时数组元素是用户名,给群组发送时数组元素是groupid
			"msg":{  //消息内容
				"type":"cmd",  // 消息类型
				"action":"action1"
			},
			"from":"testa",  //表示这个消息是谁发出来的, 可以没有这个属性, 那么就会显示是admin, 如果有的话, 则会显示是这个用户发出的
			"ext":{   //扩展属性, 由app自己定义.可以没有这个字段，但是如果有，值不能是“ext:null“这种形式，否则出错
				"attr1":"v1",
				"attr2":"v2"
			}
		}
	 */
	@SuppressWarnings("unused")
	private ObjectNode generalMsgNotice(String from, String to, Notice notice) {
		ObjectMapper mapper = new ObjectMapper();
		ObjectNode dataNode = mapper.createObjectNode();
		dataNode.put("target_type", "users");
		ArrayNode arrayNode = mapper.createArrayNode();
		for(String contact : to.split(",")){
			arrayNode.add(contact);
		}
		dataNode.put("target", arrayNode);
		
		ObjectNode _msgNode = mapper.createObjectNode();
		_msgNode.put("type", "cmd");
		_msgNode.put("action", "action1");
		dataNode.put("msg", _msgNode);
		ObjectNode _extNode = mapper.createObjectNode();
		_extNode.put("code", String.valueOf(notice.key));
		dataNode.put("ext", _extNode);
		dataNode.put("from", from);
		return dataNode;
	}
	
	public String getRequest_url() {
		return request_url;
	}
	public void setRequest_url(String request_url) {
		this.request_url = request_url;
	}
	public String getApp_user_reg_open() {
		return app_user_reg_open;
	}
	public void setApp_user_reg_open(String app_user_reg_open) {
		this.app_user_reg_open = app_user_reg_open;
	}
	public String getApp_chat_msg_limit() {
		return app_chat_msg_limit;
	}
	public void setApp_chat_msg_limit(String app_chat_msg_limit) {
		this.app_chat_msg_limit = app_chat_msg_limit;
	}
}
